package com.jh.fcsm.common;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jh.fcsm.common.exception.ServiceException;
import com.jh.fcsm.constant.Constant;
import com.jh.fcsm.util.security.UUIDUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.common.Mapper;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

public class BaseServiceImpl<M extends Mapper<T>, T> implements BaseService<T> {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected M mapper;

    @Override
    public T selectOne(T entity) {
        return mapper.selectOne(entity);
    }

    @Override
    public T selectById(Object id) {
        return mapper.selectByPrimaryKey(id);
    }

    // @Override
    // public List<T> selectListByIds(List<Object> ids) {
    // return mapper.selectByIds(ids);
    // }

    @Override
    public List<T> selectList(T entity) {
        return mapper.select(entity);
    }

    @Override
    public List<T> selectListAll() {
        return mapper.selectAll();
    }

    // @Override
    // public Long selectCountAll() {
    // return mapper.selectCount();
    // }

    @Override
    public Long selectCount(T entity) {
        return Long.valueOf(mapper.selectCount(entity));
    }

    @Override
    public void insert(T entity) {
        mapper.insert(entity);
    }

    @Override
    public void insertSelective(T entity) {
        mapper.insertSelective(entity);
    }

    @Override
    public int delete(T entity) {
        return mapper.delete(entity);
    }

    @Override
    public int deleteById(Object id) {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public int updateById(T entity) {
        return mapper.updateByPrimaryKey(entity);
    }

    @Override
    public int updateSelectiveById(T entity) {
        return mapper.updateByPrimaryKeySelective(entity);
    }

    // @Override
    // public void deleteBatchByIds(List<Object> ids) {
    // mapper.batchDeleteByIds(ids);
    // }
    //
    // @Override
    // public void updateBatch(List<T> entitys) {
    // mapper.batchUpdate(entitys);
    // }

    @Override
    public List<T> selectByExample(Object example) {
        return mapper.selectByExample(example);
    }

    @Override
    public int selectCountByExample(Object example) {
        return mapper.selectCountByExample(example);
    }

    @Override
    public T selectOneByExample(Object example) {
        return mapper.selectOneByExample(example);
    }

    /**
     * 简单分页查询
     *
     * @param pageNum
     * @param pageSize
     * @param queryEntity
     * @return
     */
    @Override
    public PageInfo<T> getBasePage(Integer pageNum, Integer pageSize, T queryEntity) {
        // 分页开始
        PageHelper.startPage(pageNum, pageSize);
        List<T> list = mapper.select(queryEntity);
        return new PageInfo<T>(list);
    }

    /**
     * 根据对象删除
     */
    @Override
    public int deleteByExample(Object example) {
        return mapper.deleteByExample(example);
    }

    /**
     * @return String[]
     * @description 获取公共属性字段
     * @author szx
     * @date 2020-9-21 8:43:05
     */
    public String[] getCommonProperties() {
        // 更新时，忽略公共字段的更新
        String[] commonProperties = new String[]{"id"};
        Field[] baseFields = BaseEntity.class.getDeclaredFields();
        String[] ignoreProperties = new String[baseFields.length];
        for (int i = 0; i < baseFields.length; i++) {
            if (!StringUtils.isEmpty(baseFields[i].getName())) {
                ignoreProperties[i] = baseFields[i].getName();
            }
        }
        ignoreProperties = StringUtils.concatenateStringArrays(ignoreProperties, commonProperties);
        return ignoreProperties;
    }

    @Override
    public void updateList(BaseEntity vo, List list, Object mapper, String linkIdparamSetMethodName) {
        try {
            Method[] methods = mapper.getClass().getMethods();
            Method methodClearByContractId = mapper.getClass().getMethod("clearByContractId", String.class);
            Method methodUpdateByPrimaryKeySelective = mapper.getClass().getMethod("updateByPrimaryKeySelective", Object.class);
            Method methodInsertSelective = mapper.getClass().getMethod("insertSelective", Object.class);
            Method linkIdparamSetMethod = null;
            Method mSetYn = null;
            methodClearByContractId.invoke(mapper, vo.getId());
            for (Object p : list) {
                BaseEntity b = (BaseEntity) p;
                linkIdparamSetMethod = linkIdparamSetMethod == null ? p.getClass().getMethod(linkIdparamSetMethodName, String.class) : linkIdparamSetMethod;
                mSetYn = mSetYn == null ? p.getClass().getMethod("setYn", Integer.class) : mSetYn;
                linkIdparamSetMethod.invoke(b, vo.getId());
                mSetYn.invoke(b, Constant.YES);
                if (b.getId() == null) {
                    b.setId(UUIDUtils.getUUID());
                    methodInsertSelective.invoke(mapper, b);
                } else {
                    methodUpdateByPrimaryKeySelective.invoke(mapper, b);
                }
            }
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new ServiceException("代码错误");
        }
    }
}
